import { Action, ActionKey } from "@/action/Action";
import { actionManager } from "@/action/ActionManager";
import ChooseElement from "@/common/ChooseElement.vue";
import { AttachedFileInfo, MenuItem, AddModelPayLoad } from "@/constants/types";
import { GraphNode } from "../../project/GraphNode";
import { modelService } from "../../service";
import { SelectOnTreeAction } from "../common/SelectOnTreeAction";
import { SetNodeInEditAction } from "./SetNodeInEditAction";
import { localFile } from "@/localFile/LocalFile";
import { MenuItemSpec } from "@/config/customSystemConfig/customSystemConfigTypes";
import { customSystemConfig } from "@/config/customSystemConfig/index";
import { arrayEqual } from "@/util/common";
import { MetaclassType } from "@/constants/MetaclassType";
import { modelTreeSelectWindow } from "@/modules/model/modals/modelTreeSelect";
import { ProjectSpecification, KeyboardEventArea, PropertyDataType } from "@/constants/Enums";
import { AuthorizedFeatures, Features } from "@/util/AuthorizedFeatures";
import { locale } from "@/util/locale";
export class OpenCreateElementAction extends Action {
  keyName = ActionKey.openCreateElement;
  desc = "打开创建元素";
  bindKey = "Ctrl+Shift+E";
  keyboardArea = KeyboardEventArea.ModelTree;

  async run(ownerId: string, metaclass: string, sts: string[] = [], fileInfo?: AttachedFileInfo, payload?: AddModelPayLoad) {
    const project = app.activeProject;
    if (!project) throw new Error("no project");
    try {
      project.attributeTabsModel.ignoreJavaModelChange = true;

      const models = await modelService.addModel(project.id, ownerId, metaclass, sts, fileInfo, false, payload);
      if (models) {
        const targetModel = models.find(model => model.metaclass === metaclass); // 只判断了metaclass，目前够用
        if (targetModel) {
          await this.afterCreateModel(targetModel.id);
          return targetModel;
        } else {
          console.error("缺少返回模型");
        }
      }
    } finally {
      project.attributeTabsModel.ignoreJavaModelChange = false;
    }
  }
  isArch() {
    const projectType = (app.activeProject?.config as any).projectSpecification;
    const isArch = projectType && [ProjectSpecification.DODAF, ProjectSpecification.UPDM, ProjectSpecification.UAF].includes(projectType);
    return isArch;
  }

  async onTreeMenuClick(graphNode: GraphNode) {
    if (graphNode.disabled) return;
    if (!app.isAppActive) return;
    // 编辑扩展包时，根节点不允许创建元素
    if (app.activeProject?.config.isProfile && !graphNode.data.ownerId) {
      return;
    }
    if (this.loading) return;
    const x = (window.event as MouseEvent)?.clientX || 100;
    const y = (window.event as MouseEvent)?.clientY || 100;
    if (x === undefined || y === undefined) {
      console.error("x or y is undefined", { x, y });
      return;
    }
    const menuList = await this.getMenuList(graphNode);
    if (menuList.length == 0) return;
    this.loading = true;
    try {
      const menuGroup = {
        ARCH_PACKAGES: { label: "包", children: [], value: "", cnName: "包", enName: "Packages" },
        ARCH_ACTUALRESOURCE: { label: "实际资源", children: [], value: "", cnName: "实际资源", enName: "Other Blocks" },
        ARCH_ARCHITECTUREMANAGEMENT: { label: "架构管理", children: [], value: "", cnName: "架构管理", enName: "Architecture Management" },
        ARCH_OPERATIONAL: {
          label: (locale.i18n.global as any).rt("@:{'terminology.operational'}"),
          children: [],
          value: "",
          cnName: "业务",
          enName: "Operational"
        },
        ARCH_PARAMETERS: { label: "参数", children: [], value: "", cnName: "参数", enName: "Parameters" },
        ARCH_PERSONNEL: { label: "人事", children: [], value: "", cnName: "人事", enName: "Personnel" },
        ARCH_PROJECTS: { label: "项目", children: [], value: "", cnName: "项目", enName: "Projects" },
        ARCH_RESOURCES: { label: "资源", children: [], value: "", cnName: "资源", enName: "Resources" },
        ARCH_SECURITY: { label: "安全", children: [], value: "", cnName: "安全", enName: "Security" },
        ARCH_SERVICES: { label: "服务", children: [], value: "", cnName: "服务", enName: "Services" },
        ARCH_STANDARDS: { label: "标准", children: [], value: "", cnName: "标准", enName: "Standards" },
        ARCH_STRATEGIC: { label: "战略", children: [], value: "", cnName: "战略", enName: "Strategic" },
        ARCH_ACTUALRESOURCES: { label: "实际资源", children: [], value: "", cnName: "实际资源", enName: "Actual Resources" },
        ARCH_SUMMARYANDOVERVIEW: { label: "总结&概述", children: [], value: "", cnName: "总结&概述", enName: "Summary and Overview" },
        GENERAL_ELEMENT: { label: "常用元素", children: [], value: "", cnName: "常用元素", enName: "Common Elements" },
        FMECA: { label: "安全和可靠性", children: [], value: "", cnName: "安全和可靠性", enName: "Security and Reliability" },
        OTHER_BLOCKS: { label: "其他模块", children: [], value: "", cnName: "其他模块", enName: "Other Blocks" },
        OTHER_REQUIREMENTS: { label: "其他需求", children: [], value: "", cnName: "其他需求", enName: "Other Requirements" }
      };

      menuList.forEach(menu => {
        console.log(menu.metaclass, 998);
        let tag;
        if (menu.tag) {
          tag = menu.tag;
        } else if (menu.metaclass === "Package" && this.isArch()) {
          tag = "ARCH_PACKAGES"; // 这个有时间迁移到后端
        } else {
          tag = "GENERAL_ELEMENT";
        }

        menuGroup[tag]?.children.push(menu);
      });

      let chooseElementMenuList = Object.values(menuGroup).filter(item => item.children.length > 0);

      // 重新排序，对应的放到首位
      let movedItemIndex = chooseElementMenuList.findIndex(it => it.label === graphNode?.data?.modelTypeCnName);
      if (movedItemIndex !== -1) {
        let movedItem = chooseElementMenuList.splice(movedItemIndex, 1)[0];
        chooseElementMenuList.unshift(movedItem);
      }

      const result: MenuItem = await ChooseElement.popup({
        x,
        y,
        title: "新建元素",
        list: chooseElementMenuList
      }).catch((err: any) => {
        err && console.error(err);
      });
      if (result) {
        if (result.tag === "FMECA") {
          if (!AuthorizedFeatures.hasAuth(Features.reliability)) {
            return;
          }
        }
        let fileInfo: AttachedFileInfo | undefined;
        if (result.appliedStereotypes && result.appliedStereotypes[0] === "Customization::AttachedFile") {
          const res = await localFile.chooseFile();

          const filePath = res.files[0]?.path;
          if (!filePath) return;
          fileInfo = await localFile.readAttachedFileInfo(filePath);
        } else if (result.metaclass === MetaclassType.Slot) {
          await this.createSlot(graphNode.data.id, result);
          return;
        }
        await this.run(graphNode.data.id, result.metaclass, result.appliedStereotypes || [], fileInfo);
      }
    } finally {
      this.loading = false;
    }
  }

  async getMenuList(graphNode: GraphNode) {
    let menuItems = await modelService.getCanCreateChildTypes(app.activeProject!.id, graphNode.id);
    if (customSystemConfig?.cteateElementMenu) {
      if (customSystemConfig.cteateElementMenu.visibleItems) {
        const visibleItems = customSystemConfig.cteateElementMenu.visibleItems;

        menuItems = menuItems.filter(item => this.filterVisibleItems(visibleItems, item));
      }
    }

    return menuItems;
  }
  filterVisibleItems(visibleItems: MenuItemSpec[], item: MenuItem): boolean {
    return !!visibleItems.find(it => {
      if (it.metaclass !== item.metaclass) return false;
      if (item.appliedStereotypes) {
        if (!it.appliedStereotypes) {
          return false;
        }
        if (!arrayEqual(it.appliedStereotypes, item.appliedStereotypes)) {
          return false;
        }
      }
      return true;
    });
  }

  async selectCreatedModel(modelId: string) {
    const selectOnTree = actionManager.getAction(ActionKey.selectOnTree) as SelectOnTreeAction;
    await selectOnTree.run([modelId], { scroll: true, changeTab: true });
  }

  /**
   * 树上，模型创建完后,等待一个step，选中模型，滚动，进入编辑状态
   */
  async afterCreateModel(modelId: string) {
    // await stepMessageHandler.waitNextStep();
    const selectOnTree = actionManager.getAction(ActionKey.selectOnTree) as SelectOnTreeAction;
    await selectOnTree.run([modelId], { scroll: true, changeTab: true });

    const setNodeInEdiAction = actionManager.getAction(ActionKey.setNodeInEdit) as SetNodeInEditAction;
    const targetNode = app.activeProject?.nodePool.getNode(modelId);
    if (targetNode) {
      setNodeInEdiAction.run(targetNode);
    } else {
      console.error("找不到模型节点", targetNode);
    }
  }

  async createSlot(ownerId: string, menuItem: MenuItem) {
    const projectId = app.activeProject!.config.id;
    const row = {
      modelId: ownerId,
      key: "Slot-definingFeature",
      dataType: PropertyDataType.INSTANCE,
      isMultiplicity: false,
      moreBtnCondition: menuItem.appliedStereotypes?.[0] || ""
    };
    const result = await modelTreeSelectWindow.popup({
      loadMethod: "getPropertyTreeList",
      showNodeLabel: true,
      loadParams: JSON.stringify({
        row,
        projectId
      }),
      multiple: false,
      attrTip: "radio",
      title: "选择定义特征"
    });
    if (result.success) {
      const propertyId = result.selectedId as string;
      await this.run(ownerId, menuItem.metaclass, menuItem.appliedStereotypes || [], undefined, { slotValue: propertyId });
    }
  }

  onKeyboardEvent(): void {
    const nodes = app.activeProject?.nodePool.getSelectedNodes();
    if (nodes?.length === 1 && !nodes[0].disabled) {
      this.onTreeMenuClick(nodes[0]);
    }
    // onTreeMenuClick
  }

  // async createAttachedFileModel(ownerId: string, metaclass: string, sts: string[] = []) {
  //   const project = app.activeProject;
  //   if (!project) throw new Error("no project");

  //   const result = await localFile.chooseFile();
  //
  //   const filePath = result.files[0]?.path;
  //   if (!filePath) return;
  //   const fileInfo = await localFile.readAttachedFileInfo(filePath);
  //   await modelService.createAttachedFileModel(project.id, ownerId, metaclass, sts, fileInfo);
  //
  // }
}
